package com.service.bracelet.controller;

import com.service.bracelet.common.CacheManager;
import com.service.bracelet.common.CommonResult;
import com.service.bracelet.common.CommonResultCode;
import com.service.bracelet.common.VerifyCacheManager;
import com.service.bracelet.entity.User;
import com.service.bracelet.service.IUserService;
import com.service.bracelet.util.JwtTokenUtil;
import com.service.bracelet.util.SecurityUtil;
import com.service.bracelet.util.UtilConsts;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private IUserService userService;

    /**
     * 登录
     *
     * @param params
     * @return
     * @throws IOException
     * @throws NoSuchAlgorithmException
     */
    @PostMapping(value = "/login")
    public CommonResult<Map<String, Object>> login(@RequestBody Map<String, Object> params, HttpServletRequest request) throws IOException, NoSuchAlgorithmException {
        return this.login(params, request, true);
    }

    /**
     * 注销
     *
     * @param params
     * @param request
     * @return
     * @throws IOException
     * @throws NoSuchAlgorithmException
     */
    @PostMapping(value = "/logout")
    public CommonResult<Void> logout(@RequestBody Map<String, Object> params, HttpServletRequest request) {
        CacheManager.remove(JwtTokenUtil.getToken(request), request);
        return CommonResult.success();
    }

    /**
     * 根据用户ID获取用户信息
     *
     * @param params
     * @return
     */
    @PostMapping(value = "/getUserInfoById")
    public CommonResult<User> getUserInfoById(@RequestBody Map<String, Object> params) {
        try {
            User user = userService.getUserById(params);
            if (user != null) {
                user.setPassword(null);
            }
            return CommonResult.success(user);
        } catch (Exception e) {
            return CommonResult.error(e);
        }
    }

    /**
     * 根据token获取当前登录用户信息
     *
     * @param params
     * @param request
     * @return
     */
    @PostMapping(value = "/getUserInfoByToken")
    public CommonResult<User> getUserInfoByToken(@RequestBody Map<String, Object> params, HttpServletRequest request) {
        try {
            params.put(UtilConsts.PARAMS_ACCOUNT, JwtTokenUtil.getUserAccount(request));
            User user = userService.getUserByAccount(params);
            user.setPassword(null);
            return CommonResult.success(user);
        } catch (Exception e) {
            return CommonResult.error(e);
        }
    }

    /**
     * 注册账号
     *
     * @param params
     * @return
     * @throws IOException
     * @throws NoSuchAlgorithmException
     */
    @PostMapping(value = "/register")
    public CommonResult<Map<String, Object>> register(@RequestBody Map<String, Object> params, HttpServletRequest request) {
        String account = MapUtils.getString(params, UtilConsts.PARAMS_ACCOUNT);
        if (StringUtils.isBlank(account)) {
            return CommonResult.error(CommonResultCode.SERVER_ERROR, "账号不能为空");
        }
        if (StringUtils.isBlank(MapUtils.getString(params, UtilConsts.PARAMS_PASSWORD))) {
            return CommonResult.error(CommonResultCode.SERVER_ERROR, "密码不能为空");
        }
        User user = userService.getUserByAccount(params);
        if (user != null) {
            return CommonResult.error(CommonResultCode.SERVER_ERROR, "账号已存在！");
        }
        try {
            userService.register(params);
            return this.login(params, request, false);
        } catch (Exception e) {
            return CommonResult.error(e);
        }
    }

    /**
     * 登录工具方法
     *
     * @param params
     * @param validatePassword
     * @return
     * @throws IOException
     * @throws NoSuchAlgorithmException
     */
    private CommonResult<Map<String, Object>> login(Map<String, Object> params, HttpServletRequest request, boolean validatePassword) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        String account = MapUtils.getString(params, UtilConsts.PARAMS_ACCOUNT);
        if (StringUtils.isBlank(account)) {
            return CommonResult.error(CommonResultCode.SERVER_ERROR, "账号为空！");
        }
        User user = userService.getUserByAccount(params);
        if (user == null) {
            return CommonResult.error(CommonResultCode.SERVER_ERROR, "用户不存在！");
        }
        if (validatePassword && !SecurityUtil.validate(MapUtils.getString(params, UtilConsts.PARAMS_PASSWORD), user.getPassword())) {
            return CommonResult.error(CommonResultCode.SERVER_ERROR, "账号密码不正确！");
        }
        if (MapUtils.getInteger(params, UtilConsts.PARAMS_USERTYPE, 0) != 0 && user.getUserType() == 0) {
            return CommonResult.error(CommonResultCode.SERVER_ERROR, "普通账号无法登录当前页面！");
        }
        user.setPassword(null);
        String token = JwtTokenUtil.generateToken(user);
        CacheManager.put(token, user, request);
        Map<String, Object> result = new HashMap<>(1);
        result.put(UtilConsts.SECURITY_HEADER, token);
        return CommonResult.success(result);
    }

    /**
     * 修改密码
     *
     * @param params
     * @param request
     * @return
     * @throws IOException
     * @throws NoSuchAlgorithmException
     */
    @PostMapping(value = "/updatePassword")
    public CommonResult<Void> updatePassword(@RequestBody Map<String, Object> params, HttpServletRequest request) {
        params.put(UtilConsts.PARAMS_ACCOUNT, JwtTokenUtil.getUserAccount(request));
        String pwd = MapUtils.getString(params, UtilConsts.PARAMS_PASSWORD);
        String oldPwd = MapUtils.getString(params, UtilConsts.PARAMS_OLDPASSWORD);
        if (StringUtils.isBlank(oldPwd)) {
            return CommonResult.error(CommonResultCode.SERVER_ERROR, "旧密码不能为空！");
        }
        if (StringUtils.isBlank(pwd)) {
            return CommonResult.error(CommonResultCode.SERVER_ERROR, "新密码不能为空！");
        }
        if (StringUtils.equals(pwd, oldPwd)) {
            return CommonResult.error(CommonResultCode.SERVER_ERROR, "新旧密码相同！");
        }
        try {
            User user = userService.getUserByAccount(params);
            if (!SecurityUtil.validate(oldPwd, user.getPassword())) {
                return CommonResult.error(CommonResultCode.SERVER_ERROR, "旧密码不正确！");
            }
            params.put(UtilConsts.PARAMS_USERID, JwtTokenUtil.getUserId(request));
            userService.updatePassword(params);
            return CommonResult.success();
        } catch (Exception e) {
            return CommonResult.error(e);
        }
    }

    /**
     * 根据用户ID重置密码，重置后密码为123456
     *
     * @param params
     * @param request
     * @return
     * @throws IOException
     * @throws NoSuchAlgorithmException
     */
    @PostMapping(value = "/resetPassword")
    public CommonResult<Void> resetPassword(@RequestBody Map<String, Object> params, HttpServletRequest request) {
        if (StringUtils.isBlank(MapUtils.getString(params, UtilConsts.PARAMS_USERID))) {
            return CommonResult.error(CommonResultCode.SERVER_ERROR, "用户ID没设置！");
        }
        try {
            JwtTokenUtil.checkAdmin(request);
            userService.resetPassword(params);
            return CommonResult.success();
        } catch (Exception e) {
            return CommonResult.error(e);
        }
    }

    /**
     * 修改用户信息
     *
     * @param params
     * @param request
     * @return
     */
    @PostMapping(value = "/updateInfo")
    public CommonResult<Void> updateInfo(@RequestBody Map<String, Object> params, HttpServletRequest request) {
        try {
            params.put(UtilConsts.PARAMS_USERID, JwtTokenUtil.getUserId(request));
            userService.updateInfo(params);
            return CommonResult.success();
        } catch (Exception e) {
            return CommonResult.error(e);
        }
    }

    /**
     * 查询所有用户信息，管理员查看
     */
    @PostMapping(value = "/queryList")
    public CommonResult<List<User>> queryList(@RequestBody Map<String, Object> params, HttpServletRequest request) {
        try {
            JwtTokenUtil.checkAdmin(request);
            return userService.queryList(params);
        } catch (Exception e) {
            return CommonResult.error(e);
        }
    }

    /**
     * 验证账号
     */
    @PostMapping(value = "/verifyAccount")
    public CommonResult<Map<String, Object>> verifyAccount(@RequestBody Map<String, Object> params, HttpServletRequest request) {
        String account = MapUtils.getString(params, UtilConsts.PARAMS_ACCOUNT);
        if (StringUtils.isBlank(account)) {
            return CommonResult.error(CommonResultCode.SERVER_ERROR, "账号为空！");
        }
        try {
            User user = userService.getUserByAccount(params);
            if (user != null) {
                user.setPassword(null);
                Map<String, Object> map = new HashMap<>(1);
                map.put(UtilConsts.SECURITY_USER, user);
                map.put(UtilConsts.SECURITY_VERIFY_STATE, UtilConsts.SECURITY_VERIFY_STATE_ANSWER);
                String token = JwtTokenUtil.generateToken(map);
                VerifyCacheManager.put(token, map);
                Map<String, Object> result = new HashMap<>(1);
                result.put(UtilConsts.SECURITY_VERIFY_TOKEN, token);
                return CommonResult.success(result);
            } else {
                return CommonResult.error(CommonResultCode.SERVER_ERROR, "用户ID没设置！");
            }
        } catch (Exception e) {
            return CommonResult.error(e);
        }
    }

    /**
     * 回到问题
     */
    @PostMapping(value = "/answerQuestion")
	public CommonResult<Void> answerQuestion(@RequestBody Map<String, Object> params, HttpServletRequest request) {
		if (MapUtils.getInteger(params, UtilConsts.PARAMS_QUESTIONID) == null) {
			return CommonResult.error(CommonResultCode.SERVER_ERROR, "请选择问题！");
		}
		if (StringUtils.isBlank(MapUtils.getString(params, UtilConsts.PARAMS_ANSWER))) {
			return CommonResult.error(CommonResultCode.SERVER_ERROR, "答案为空！");
		}
		String token = JwtTokenUtil.getVerifyToken(request);
		Map<String, Object> map = VerifyCacheManager.get(token);
		if (map == null) {
			return CommonResult.error(CommonResultCode.SERVER_ERROR, "验证状态失效，请重新进行验证！");
		}
		String state = MapUtils.getString(map, UtilConsts.SECURITY_VERIFY_STATE);
		if (StringUtils.equals(UtilConsts.SECURITY_VERIFY_STATE_ANSWER, state)) {
			return CommonResult.error(CommonResultCode.SERVER_ERROR, "当前不是回答问题状态，无法更新密码！");
		}
		try {
			User user = (User) map.get(UtilConsts.SECURITY_USER);
			params.put(UtilConsts.PARAMS_ACCOUNT, user.getAccount());
			if (userService.answerQuestion(params)) {
				map.put(UtilConsts.SECURITY_VERIFY_STATE, UtilConsts.SECURITY_VERIFY_STATE_NEWPASSWORD);
				return CommonResult.success();
			} else {
				return CommonResult.error(CommonResultCode.SERVER_ERROR, "问题验证失败！");
			}
		} catch (Exception e) {
			return CommonResult.error(e);
		}
	}

    /**
     * 更新密码
     */
    @PostMapping(value = "/newPassword")
    public CommonResult<Map<String, Object>> newPassword(@RequestBody Map<String, Object> params, HttpServletRequest request) {
        if (StringUtils.isBlank(MapUtils.getString(params, UtilConsts.PARAMS_PASSWORD))) {
            return CommonResult.error(CommonResultCode.SERVER_ERROR, "密码不能为空！");
        }
        String token = JwtTokenUtil.getVerifyToken(request);
        Map<String, Object> map = VerifyCacheManager.get(token);
        String state = MapUtils.getString(map, UtilConsts.SECURITY_VERIFY_STATE);
        if (StringUtils.equals(UtilConsts.SECURITY_VERIFY_STATE_NEWPASSWORD, state)) {
            return CommonResult.error(CommonResultCode.SERVER_ERROR, "当前不是更新密码状态，无法更新密码！");
        }
        try {
            User user = (User) map.get(UtilConsts.SECURITY_USER);
            params.put(UtilConsts.PARAMS_USERID, user.getId());
            userService.updatePassword(params);
            VerifyCacheManager.remove(token);

            token = JwtTokenUtil.generateToken(user);
            CacheManager.put(token, user, request);
            Map<String, Object> result = new HashMap<>(1);
            result.put(UtilConsts.SECURITY_HEADER, token);
            return CommonResult.success(result);
        } catch (Exception e) {
            return CommonResult.error(e);
        }
    }
}
